package com.powergisol.gis.util;

import org.apache.commons.codec.binary.Base64;

import java.io.*;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.Scanner;

/**
 * 序列号工具类(获取计算机CPU、硬盘、主板等信息序列号，生成机器码)
 * @author rxj created by 2018/1/22
 */
public class MachineCodeUtil {
    /**
     * 构造函数私有化
     */
    private MachineCodeUtil(){}

    /**
     * 生成机器码(BASE64)
     * @return
     */
    public static String generateMachineCode(){
        //机器码(cpu+主板序列号构成)
        String code = cpuSerialNumber()+"@@"+getMotherboardSN()+"@@"+hardDiskSerialNumber(getDriver())+"@@"+getMACAddress();
        
        return Base64.encodeBase64String(code.getBytes());
    }

    /**
     * 获取CPU序列号
     * @return
     */
    private static String cpuSerialNumber(){
        try {
            Process process = Runtime.getRuntime().exec(
                    new String[] { "wmic", "cpu", "get", "ProcessorId" });
            process.getOutputStream().close();
            Scanner sc = new Scanner(process.getInputStream());
            String property = sc.next();
            return sc.next();
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 获取主板序列号
     * @return
     */
    private static String getMotherboardSN() {
        String result = "";
        try {
            File file = File.createTempFile("realhowto", ".vbs");
            file.deleteOnExit();
            FileWriter fw = new FileWriter(file);
            String vbs = "Set objWMIService = GetObject(\"winmgmts:\\\\.\\root\\cimv2\")\n"
                    + "Set colItems = objWMIService.ExecQuery _ \n"
                    + "   (\"Select * from Win32_BaseBoard\") \n"
                    + "For Each objItem in colItems \n"
                    + "    Wscript.Echo objItem.SerialNumber \n"
                    + "    exit for  ' do the first cpu only! \n" + "Next \n";
            fw.write(vbs);
            fw.close();
            Process p = Runtime.getRuntime().exec(
                    "cscript //NoLogo " + file.getPath());
            BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
            String line;
            while ((line = input.readLine()) != null) {
                result += line;
            }
            input.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result.trim();
    }

    /**
     * 获取硬盘序列号
     * @param drive 盘符
     * @return
     */
    private static String hardDiskSerialNumber(String drive) {
        String result = "";
        try {
            File file = File.createTempFile("realhowto",".vbs");
            file.deleteOnExit();
            FileWriter fw = new FileWriter(file);
            String vbs = "Set objFSO = CreateObject(\"Scripting.FileSystemObject\")\n"
                    +"Set colDrives = objFSO.Drives\n"
                    +"Set objDrive = colDrives.item(\"" + drive + "\")\n"
                    +"Wscript.Echo objDrive.SerialNumber";  // see note
            fw.write(vbs);
            fw.close();
            Process p = Runtime.getRuntime().exec("cscript //NoLogo " + file.getPath());
            BufferedReader input =
                    new BufferedReader
                            (new InputStreamReader(p.getInputStream()));
            String line;
            while ((line = input.readLine()) != null) {
                result += line;
            }
            input.close();
        }
        catch(Exception e){
            e.printStackTrace();
        }
        return result.trim();
    }

    private static String getMACAddress() {

        InetAddress address ;
        byte[] mac = new byte[0];
        try {
            address = InetAddress.getLocalHost();

            // 获得网络接口对象（即网卡），并得到mac地址，mac地址存在于一个byte数组中。
            mac = NetworkInterface.getByInetAddress(address).getHardwareAddress();
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 下面代码是把mac地址拼装成String
        StringBuffer sb = new StringBuffer();

        for (int i = 0; i < mac.length; i++) {
            if (i != 0) {
                sb.append("-");
            }
            // mac[i] & 0xFF 是为了把byte转化为正整数
            String s = Integer.toHexString(mac[i] & 0xFF);
            sb.append(s.length() == 1 ? 0 + s : s);
        }
        // 把字符串所有小写字母改为大写成为正规的mac地址并返回
        return sb.toString().toUpperCase();
    }

    private static String getDriver(){
        String workDir = System.getProperties().getProperty("user.dir");

        if(workDir.length()>0){
            return workDir.substring(0,1);
        }else{
            throw new RuntimeException("未找到平台工作目录，请检查安装位置");
        }

    }

    public boolean checkLicense(){
        String cpuId = cpuSerialNumber();
        String driverId = hardDiskSerialNumber(getDriver());
        String mac = getMACAddress();
        return  false;
    }

    public static void main(String[] args) throws IOException {
       String st = generateMachineCode();

        BufferedInputStream bis = new BufferedInputStream(new ByteArrayInputStream(st.getBytes()));
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("D://NDKJ-License"));


       int data;
       while((data=bis.read())!=-1){
           bos.write(data^0xFF);
       }
       bos.flush();
       bos.close();
       bis.close();
    }
}
